<!DOCTYPE html>
<html>
  <head>
    <title>Four-dimensional hypercube visualization</title>
    <style>
      canvas {
        border: 1px solid black;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="500" height="500"></canvas>
    <script>
      const canvas = document.getElementById('canvas')
      const context = canvas.getContext('2d')

      const dimension = 4 // 四维空间
      const n = 512 // 16个点

      // 初始化点的坐标和颜色
      const points = []
      for (let i = 0; i < n; i++) {
        const point = []
        for (let j = 0; j < dimension; j++) {
          point.push(Math.random() * 2 - 1) // 随机生成在 [-1, 1] 范围内的坐标
        }
        points.push({
          position: point,
          color: `rgb(${Math.random() * 255},${Math.random() * 255},${
            Math.random() * 255
          })`, // 随机生成颜色
        })
      }

      // 投影到三维空间
      function project(point) {
        const w = 1 // 四维超立方体的第四个坐标，取值为1
        const projectionMatrix = [
          [1, 0, 0, 0],
          [0, 1, 0, 0],
          [0, 0, 1, 0],
          [0, 0, 0, 0],
        ]
        const projected = [0, 0, 0]
        for (let i = 0; i < 3; i++) {
          for (let j = 0; j < dimension; j++) {
            projected[i] += projectionMatrix[i][j] * point.position[j]
          }
        }
        return projected
      }

      // 绘制四维超立方体
      function draw() {
        context.clearRect(0, 0, canvas.width, canvas.height)
        context.beginPath()
        for (let i = 0; i < n; i++) {
          const point = project(points[i])
          context.moveTo(point[0] * 100 + 250, point[1] * 100 + 250)
          for (let j = i + 1; j < n; j++) {
            const otherPoint = project(points[j])
            context.lineTo(otherPoint[0] * 100 + 250, otherPoint[1] * 100 + 250)
            // 新加的
            context.strokeStyle = points[j].color
            context.stroke()
            context.beginPath()
          }
        }
        context.stroke()
      }

      // 动画循环
      function animate() {
        requestAnimationFrame(animate)
        // 更新点的位置
        for (let i = 0; i < n; i++) {
          const point = points[i]
          for (let j = 0; j < dimension; j++) {
            point.position[j] += (Math.random() * 2 - 1) * 0.01 // 随机变化点的坐标
          }
        }
        draw()
      }

      animate()
    </script>
  </body>
</html>
